home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / exec / allocsignal.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  3KB  |  127 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: allocsignal.c,v 1.4 1996/08/13 13:55:58 digulla Exp $
  4.     $Log: allocsignal.c,v $
  5.     Revision 1.4  1996/08/13 13:55:58  digulla
  6.     Replaced __AROS_LA by __AROS_LHA
  7.     Replaced some __AROS_LH*I by __AROS_LH*
  8.     Sorted and added includes
  9.  
  10.     Revision 1.3  1996/08/01 17:41:05  digulla
  11.     Added standard header for all files
  12.  
  13.     Desc:
  14.     Lang:
  15. */
  16. #include <exec/execbase.h>
  17. #include <exec/tasks.h>
  18. #include <aros/libcall.h>
  19.  
  20. /*****************************************************************************
  21.  
  22.     NAME */
  23.     #include <clib/exec_protos.h>
  24.  
  25. __AROS_LH1(BYTE, AllocSignal,
  26.  
  27. /*  SYNOPSIS */
  28.     __AROS_LHA(LONG, signalNum, D0),
  29.  
  30. /*  LOCATION */
  31.     struct ExecBase *, SysBase, 55, Exec)
  32.  
  33. /*  FUNCTION
  34.     Allocate a given signal out of the current task's pool of signals.
  35.     Every task has a set of signals to communicate with other tasks.
  36.     Half of them are reserved for the system and half of them is
  37.     free for general use. Some of the reserved signals (e.g.
  38.     SIGBREAKF_CTRL_C) have a defined behaviour and may be used by user
  39.     code, however.
  40.  
  41.     INPUTS
  42.     signalNum - Number of the signal to allocate or -1 if any signal
  43.             will do.
  44.  
  45.     RESULT
  46.     Number of the signal or -1 if the signal couldn't be allocated.
  47.  
  48.     NOTES
  49.  
  50.     EXAMPLE
  51.  
  52.     BUGS
  53.  
  54.     SEE ALSO
  55.     FreeSignal(), Signal(), Wait()
  56.  
  57.     INTERNALS
  58.  
  59.     HISTORY
  60.  
  61. ******************************************************************************/
  62. {
  63.     __AROS_FUNC_INIT
  64.  
  65.     ULONG *mask;
  66.     ULONG mask1;
  67.  
  68.     /* Protect signal mask against possible task exceptions. */
  69.     Forbid();
  70.  
  71.     /* Get pointer to mask of allocated signal */
  72.     mask=&SysBase->ThisTask->tc_SigAlloc;
  73.  
  74.     /* Get signal */
  75.     if(signalNum<0)
  76.     {
  77.     /* Any signal will do. */
  78.  
  79.     /*
  80.      * To get the last nonzero bit in a number I use a&~a+1:
  81.      * Given a number that ends with a row of zeros  xxxx1000
  82.      * I first toggle all bits in that number     XXXX0111
  83.      * then add 1 to toggle all but the last 0 again XXXX1000
  84.      * and AND this with the original number     00001000
  85.      *
  86.      * And since ~a+1=-a I can use a&-a instead.
  87.      *
  88.      * And to get the last zero bit I finally use ~a&-~a.
  89.      */
  90.     mask1=~*mask&-~*mask;
  91.  
  92.     /* Got a bit? */
  93.     if(mask1)
  94.     {
  95.         /* Allocate and reset the bit */
  96.         *mask|=mask1;
  97.         SysBase->ThisTask->tc_SigRecvd&=~mask1;
  98.  
  99.         /* And get the bit number */
  100.         signalNum=(mask1&0xffff0000?16:0)+(mask1&0xff00ff00?8:0)+
  101.               (mask1&0xf0f0f0f0? 4:0)+(mask1&0xcccccccc?2:0)+
  102.               (mask1&0xaaaaaaaa? 1:0);
  103.     }
  104.     }else
  105.     {
  106.     /* Get a specific signal */
  107.     mask1=1<<signalNum;
  108.  
  109.     /* Check if signal is free */
  110.     if(*mask&mask1)
  111.         /* No. Return */
  112.         signalNum=-1;
  113.     else
  114.     {
  115.         /* It is free. Allocate and reset it. */
  116.         *mask|=mask1;
  117.         SysBase->ThisTask->tc_SigRecvd&=~mask1;
  118.     }
  119.     }
  120.  
  121.     Permit();
  122.  
  123.     return signalNum;
  124.     __AROS_FUNC_EXIT
  125. }
  126.  
  127.